#include "CharacterEditForm.h"
#include "ui_CharacterEditForm.h"



#include "ClassSkillProxy.h"
#include "CampaignViewDelegate.h"



#include <CharacterItem.h>
#include <CampaignItem.h>
#include <FileHandler.h>



CharacterEditFormBase::CharacterEditFormBase(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CharacterEditForm)
{
    ui->setupUi(this);
    ui->treeViewData->setItemDelegate(new CampaignViewDelegate(this));

    on_pushButtonAbilities_clicked();
    on_pushButtonDescription_clicked();

    addAction(ui->actionChange_View);
    addAction(ui->actionAdd_Group);
    addAction(ui->actionAdd_Item);
    addAction(ui->actionDelete);
    addAction(ui->actionAdd_Reference);

    foreach (QAction* act, actions())
    {
        if (act == ui->actionChange_View) continue;

        act->setEnabled(false);
    }
}



CharacterEditFormBase::~CharacterEditFormBase()
{
    delete ui;
}



void CharacterEditFormBase::updateData()
{
    on_lineEditName_editingFinished();
}



void CharacterEditFormBase::initialize()
{
    ItemModel* itemModel = model();
    if (!itemModel) return;

    ui->treeViewData->setModel(itemModel);

    CharacterItem* characterRoot = dynamic_cast<CharacterItem*>(itemModel->rootItem());
    if (!characterRoot) return;

    ui->lineEditName->setText(characterRoot->name());

    openCampaign(characterRoot->campaignFile());


    // Class skill proxy

    ClassSkillProxy* skillProxy = new ClassSkillProxy(this);
    skillProxy->setItemModel(itemModel);
    ui->treeViewSkills->setModel(skillProxy);


    // Class features proxy

    SimpleProxyModel* featureProxy = new SimpleProxyModel(this);
    featureProxy->addIncludeFilter("((\\S)+)Class([ ]{0,1})Features((\\S)+)", SimpleProxyModel::RegExpFilter);
    featureProxy->addExcludeFilter(".Reference");

    featureProxy->addField(AbstractItem::NameData, "Class Features");
    featureProxy->addField(AbstractItem::IdData, "Value");
    featureProxy->setItemModel(itemModel);

    ui->treeViewFeatures->setModel(featureProxy);


    // Item view headers

    ui->treeViewData->header()->setResizeMode(QHeaderView::ResizeToContents);
    ui->treeViewSkills->header()->setResizeMode(QHeaderView::ResizeToContents);

}



void CharacterEditFormBase::openCampaign(const QString& campaign_file)
{
    if (campaign_file.isEmpty() || !QFile::exists(campaign_file)) return;

    CampaignItem* campaignRoot = dynamic_cast<CampaignItem*>(FileHandler::open(campaign_file));
    if (!campaignRoot) return;

    ItemModel* itemModel = model();
    if (!itemModel) return;

    CharacterItem* characterRoot = dynamic_cast<CharacterItem*>(itemModel->rootItem());
    if (!characterRoot) return;

    characterRoot->setCampaign(campaignRoot);

    QString campaignName = characterRoot->campaignName();
    if (!campaignName.isEmpty())
    {
        ui->pushButtonCampaign->setText(campaignName + "...");
        return;
    }

    ui->pushButtonCampaign->setText(tr("Campaign..."));
}



void CharacterEditFormBase::on_pushButtonAbilities_clicked()
{
    ui->plainTextEditAbilities->setVisible(ui->pushButtonAbilities->isChecked());
}



void CharacterEditFormBase::on_pushButtonDescription_clicked()
{
    ui->plainTextEditDescription->setVisible(ui->pushButtonDescription->isChecked());
}



void CharacterEditFormBase::on_actionChange_View_triggered()
{
    if (ui->stackedWidget->currentWidget() == ui->pageData) ui->stackedWidget->setCurrentWidget(ui->pageEdit);
    else ui->stackedWidget->setCurrentWidget(ui->pageData);

    ui->actionAdd_Group->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
    ui->actionAdd_Item->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
    ui->actionDelete->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
    ui->actionAdd_Reference->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
}



void CharacterEditFormBase::on_lineEditName_editingFinished()
{
    ItemModel* itemModel = model();
    if (!itemModel) return;

    CharacterItem* characterRoot = dynamic_cast<CharacterItem*>(itemModel->rootItem());
    if (!characterRoot) return;

    characterRoot->setData(AbstractItem::NameData, ui->lineEditName->text());
}



void CharacterEditFormBase::on_pushButtonCampaign_clicked()
{
    ItemModel* itemModel = model();
    if (!itemModel) return;

    CharacterItem* characterRoot = dynamic_cast<CharacterItem*>(itemModel->rootItem());
    if (!characterRoot) return;

    QString campaignFile = characterRoot->campaignFile();
    QString campaignDir = QDir::currentPath();
    if (!campaignFile.isEmpty() && QFile::exists(campaignFile))
    {
        campaignDir = QFileInfo(campaignFile).absolutePath();
    }

    campaignFile = QFileDialog::getOpenFileName(this, tr("Select Campaign File"), campaignDir, tr("Xml File (*.xml)"));
    openCampaign(campaignFile);

}



void CharacterEditFormBase::on_actionAdd_Group_triggered()
{
    QAbstractItemModel* model = ui->treeViewData->model();
    if (!model) return;

    model->insertRows(model->rowCount(QModelIndex()), 1, QModelIndex());
    ui->treeViewData->setCurrentIndex(model->index(model->rowCount(QModelIndex())-1,0,QModelIndex()));
}



void CharacterEditFormBase::on_actionAdd_Item_triggered()
{
    QAbstractItemModel* model = ui->treeViewData->model();
    if (!model) return;

    QModelIndex index = ui->treeViewData->currentIndex();
    if (!index.isValid()) return;

    QVariant category = index.sibling(index.row(), AbstractItem::CategoryData).data(Qt::EditRole);
    if (!category.isValid()) return;

    QModelIndex parent;
    switch (category.toInt())
    {
    case ItemCategory_Root: return;
    case ItemCategory_Group: { parent = index; break; }
    case ItemCategory_Item:  { parent = index.parent(); break; }
    case ItemCategory_Reference: { parent = index.parent().parent(); break; }
    default: return;
    }

    model->insertRows(model->rowCount(parent), 1, parent);
    ui->treeViewData->setCurrentIndex(model->index(model->rowCount(parent)-1,0,parent));
}



void CharacterEditFormBase::on_actionDelete_triggered()
{
    QAbstractItemModel* model = ui->treeViewData->model();
    if (!model) return;

    QModelIndex index = ui->treeViewData->currentIndex();
    if (!index.isValid()) return;

    model->removeRows(index.row(), 1, index.parent());
}



void CharacterEditFormBase::on_actionAdd_Reference_triggered()
{
    QAbstractItemModel* model = ui->treeViewData->model();
    if (!model) return;

    QModelIndex index = ui->treeViewData->currentIndex();
    if (!index.isValid()) return;

    QVariant category = index.sibling(index.row(), AbstractItem::CategoryData).data(Qt::EditRole);
    if (!category.isValid()) return;

    QModelIndex parent;
    switch (category.toInt())
    {
    case ItemCategory_Item:         { parent = index; break; }
    case ItemCategory_Reference:    { parent = index.parent(); break; }

    case ItemCategory_Root:         return;
    case ItemCategory_Group:        return;
    default: return;
    }

    model->insertRows(model->rowCount(parent), 1, parent);
    ui->treeViewData->setCurrentIndex(model->index(model->rowCount(parent)-1,0,parent));
}


